package com.atshiyou.mvc;

import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * 映射器（包含了大量的网址与方法的对应关系）
 */
public class HandlerMapping {
    private static Map<String, MVCMapping> data = new HashMap<>();

    public static MVCMapping get(String uri) {
        return data.get(uri);
    }


    public static void load(InputStream is) throws Exception {
        Properties properties = new Properties();
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Collection<Object> values = properties.values();//获取到的配置文件的值，是 等号 右边的值，是一个个类型
        for (Object cla : values) {
            String className = (String) cla; //获取类的名称
            //反射开始
            Class c = Class.forName(className);
            Object obj = c.getConstructor().newInstance(); // 调用无参构造方法获取对象
            //获取这个类中的所有通用方法
            Method[] methods = c.getMethods();
            for (Method method : methods) {
                //获取方法上的注解
                Annotation[] annotations = method.getAnnotations();
                if (annotations != null) {
                    for (Annotation annotation : annotations) {
                        if (annotation instanceof ResponseBody) {
                            //如果方法上的注解类型是ResponseBody，说明此方法用于 以文字形式返回到客户端
                            /**
                             * 这句代码将前面铺垫的反射和枚举，注解联系了起来
                             */
                            MVCMapping mvcMapping = new MVCMapping(obj, method, ResponseType.TEXT);
                            data.put(((ResponseBody) annotation).value(), mvcMapping);
                        } else if (annotation instanceof ResponseView) {
                            //如果方法上的注解类型是ResponseView，说明此方法用于 返回界面到客户端
                            MVCMapping mvcMapping = new MVCMapping(obj, method, ResponseType.VIEW);
                            data.put(((ResponseView) annotation).value(), mvcMapping);

                        }
                    }

                }
            }
        }

    }

    /**
     * 映射对象，每一个对象封装了一个方法，用于处理请求
     */
    public static class MVCMapping {
        private Object obj; //对象
        private Method method; // 反射方法
        private ResponseType type; // 注解类型

        public MVCMapping(Object obj, Method method, ResponseType type) {
            this.obj = obj;
            this.method = method;
            this.type = type;
        }


        public Object getObj() {
            return obj;
        }


        public Method getMethod() {
            return method;
        }


        public ResponseType getType() {
            return type;
        }


    }
}
